Sužinokite, kaip efektyviai kategorizuoti ir tvarkyti klaidas React Error Boundaries, pagerinant programos stabilumą ir vartotojo patirtį.
React Error Boundary klaidų kategorizavimas: Išsamus vadovas
Klaidų tvarkymas yra kritinis aspektas kuriant patikimas ir prižiūrimas React programėles. Nors React Error Boundaries suteikia mechanizmą grakščiai tvarkyti klaidas, kurios atsiranda atvaizdavimo metu, supratimas, kaip kategorizuoti ir reaguoti į skirtingus klaidų tipus, yra būtinas kuriant tikrai atsparią programą. Šis vadovas nagrinėja įvairius klaidų kategorizavimo metodus Error Boundaries viduje, siūlydamas praktinius pavyzdžius ir įžvalgas, kurios pagerins jūsų klaidų valdymo strategiją.
Kas yra React Error Boundaries?
Pristatyti React 16, Error Boundaries yra React komponentai, kurie gaudo JavaScript klaidas bet kurioje jų vaikų komponentų medžio vietoje, registruoja tas klaidas ir rodo atsarginę UI vietoj to, kad sugriautų visą komponentų medį. Jie veikia panašiai kaip try...catch blokas, bet komponentams.
Pagrindinės Error Boundaries charakteristikos:
- Komponentų lygio klaidų tvarkymas: Izoliuoti klaidas konkrečiose komponentų pomedžiuose.
- Grakštus degradavimas: Apsaugo visą programą nuo gedimo dėl vienos komponento klaidos.
- Valdoma atsarginė UI: Rodyti vartotojui patogų pranešimą arba alternatyvų turinį, kai atsiranda klaida.
- Klaidų registravimas: Palengvinti klaidų sekimą ir derinimo procesą, registruojant informaciją apie klaidas.
Kodėl kategorizuoti klaidas Error Boundaries?
Nepakanka tiesiog užfiksuoti klaidas. Efektyvus klaidų tvarkymas reikalauja suprasti, kas nutiko ir atitinkamai reaguoti. Klaidų kategorizavimas Error Boundaries viduje suteikia keletą privalumų:
- Tikslinis klaidų tvarkymas: Skirtingi klaidų tipai gali reikalauti skirtingų atsakymų. Pavyzdžiui, tinklo klaida gali pateisinti pakartotinį bandymo mechanizmą, o duomenų patvirtinimo klaida gali reikalauti vartotojo įvesties pataisymo.
- Pagerinta vartotojo patirtis: Rodyti informatyvesnius klaidų pranešimus, pagrįstus klaidos tipu. Bendras pranešimas „Kažkas nuėjo ne taip“ yra mažiau naudingas nei konkretus pranešimas, rodantis tinklo problemą arba neteisingą įvestį.
- Pagerintas derinimas: Klaidų kategorizavimas suteikia vertingą kontekstą derinant ir nustatant pagrindinę problemų priežastį.
- Proaktyvus stebėjimas: Stebėkite skirtingų klaidų tipų dažnumą, kad nustatytumėte pasikartojančias problemas ir prioritetizuotumėte pataisymus.
- Strateginė atsarginė UI: Rodyti skirtingas atsargines UI, priklausomai nuo klaidos, suteikiant daugiau aktualios informacijos arba veiksmų vartotojui.
Klaidų kategorizavimo metodai
Klaidoms kategorizuoti React Error Boundaries viduje gali būti naudojamos kelios technikos:
1. Naudojant instanceof
instanceof operatorius tikrina, ar objektas yra tam tikros klasės egzempliorius. Tai naudinga kategorizuojant klaidas pagal jų įmontuotus arba pasirinktinius klaidų tipus.
Pavyzdys:
class NetworkError extends Error {
constructor(message) {
super(message);
this.name = "NetworkError";
}
}
class ValidationError extends Error {
constructor(message) {
super(message);
this.name = "ValidationError";
}
}
class MyErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null, errorInfo: null };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true, error: error };
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
console.error("Caught error:", error, errorInfo);
this.setState({errorInfo: errorInfo});
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
let errorMessage = "Something went wrong.";
if (this.state.error instanceof NetworkError) {
errorMessage = "Įvyko tinklo klaida. Patikrinkite savo ryšį ir bandykite dar kartą.";
} else if (this.state.error instanceof ValidationError) {
errorMessage = "Įvyko patvirtinimo klaida. Peržiūrėkite savo įvestį.";
}
return (
<div>
<h2>Klaida!</h2>
<p>{errorMessage}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.toString()}<br />
{this.state.errorInfo.componentStack}
</details>
</div>
);
}
return this.props.children;
}
}
Paaiškinimas:
- Apibrėžiamos pasirinktinės
NetworkErrorirValidationErrorklasės, plėsdamos įmontuotąErrorklasę. MyErrorBoundarykomponentorendermetode naudojamasinstanceofoperatorius, norint patikrinti užfiksuotos klaidos tipą.- Remiantis klaidos tipu, atsarginėje UI rodomas konkretus klaidų pranešimas.
2. Naudojant klaidų kodus arba savybes
Kitas metodas yra įtraukti klaidų kodus arba savybes į patį klaidų objektą. Tai leidžia smulkiau kategorizuoti pagal konkrečius klaidų scenarijus.
Pavyzdys:
function fetchData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
if (!response.ok) {
const error = new Error("Network request failed");
error.code = response.status; // Add a custom error code
reject(error);
}
return response.json();
})
.then(data => resolve(data))
.catch(error => reject(error));
});
}
class MyErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null, errorInfo: null };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
return { hasError: true, error: error };
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
console.error("Caught error:", error, errorInfo);
this.setState({errorInfo: errorInfo});
}
render() {
if (this.state.hasError) {
let errorMessage = "Something went wrong.";
if (this.state.error.code === 404) {
errorMessage = "Resursas nerastas.";
} else if (this.state.error.code >= 500) {
errorMessage = "Serverio klaida. Bandykite dar kartą vėliau.";
}
return (
<div>
<h2>Klaida!</h2>
<p>{errorMessage}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.toString()}<br />
{this.state.errorInfo.componentStack}
</details>
</div>
);
}
return this.props.children;
}
}
Paaiškinimas:
fetchDatafunkcija pridedacodesavybę prie klaidų objekto, nurodančio HTTP būsenos kodą.MyErrorBoundarykomponentas tikrinacodesavybę, kad nustatytų konkretų klaidų scenarijų.- Skirtingi klaidų pranešimai rodomi pagal klaidų kodą.
3. Naudojant centralizuotą klaidų atvaizdavimą
Sudėtingoms programoms centralizuoto klaidų atvaizdavimo palaikymas gali pagerinti kodo organizavimą ir priežiūrą. Tai apima žodyno arba objekto, kuris susieja klaidų tipus arba kodus su konkrečiais klaidų pranešimais ir tvarkymo logika, sukūrimą.
Pavyzdys:
const errorMap = {
"NETWORK_ERROR": {
message: "Įvyko tinklo klaida. Patikrinkite savo ryšį.",
retry: true,
},
"INVALID_INPUT": {
message: "Neteisinga įvestis. Peržiūrėkite savo duomenis.",
retry: false,
},
404: {
message: "Resursas nerastas.",
retry: false,
},
500: {
message: "Serverio klaida. Bandykite dar kartą vėliau.",
retry: true,
},
"DEFAULT": {
message: "Something went wrong.",
retry: false,
},
};
function handleCustomError(errorType) {
const errorDetails = errorMap[errorType] || errorMap["DEFAULT"];
return errorDetails;
}
class MyErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, errorDetails: null, errorInfo: null };
}
static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
const errorDetails = handleCustomError(error.message);
return { hasError: true, errorDetails: errorDetails };
}
componentDidCatch(error, errorInfo) {
// You can also log the error to an error reporting service
console.error("Caught error:", error, errorInfo);
this.setState({errorInfo: errorInfo});
}
render() {
if (this.state.hasError) {
const { message } = this.state.errorDetails;
return (
<div>
<h2>Klaida!</h2>
<p>{message}</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.errorDetails.message}<br />
{this.state.errorInfo.componentStack}
</details>
</div>
);
}
return this.props.children;
}
}
function MyComponent(){
const [data, setData] = React.useState(null);
React.useEffect(() => {
try {
throw new Error("NETWORK_ERROR");
} catch (e) {
throw e;
}
}, []);
return <div></div>;
}
Paaiškinimas:
errorMapobjektas saugo informaciją apie klaidą, įskaitant pranešimus ir pakartotinio bandymo vėliavėles, atsižvelgiant į klaidų tipus arba kodus.handleCustomErrorfunkcija gauna informaciją apie klaidą išerrorMap, remdamasi klaidų pranešimu, ir grąžina numatytuosius nustatymus, jei nerastas joks konkretus kodas.MyErrorBoundarykomponentas naudojahandleCustomError, kad gautų atitinkamą klaidų pranešimą išerrorMap.
Geriausia klaidų kategorizavimo praktika
- Apibrėžkite aiškius klaidų tipus: Nustatykite nuoseklų klaidų tipų arba kodų rinkinį savo programai.
- Pateikite kontekstinę informaciją: Įtraukite atitinkamą informaciją į klaidų objektus, kad palengvintumėte derinimo procesą.
- Centralizuokite klaidų tvarkymo logiką: Naudokite centralizuotą klaidų atvaizdavimą arba pagalbinės funkcijas, kad nuosekliai valdytumėte klaidų tvarkymą.
- Efektyviai registruokite klaidas: Integruokite klaidų registravimo paslaugas, kad galėtumėte stebėti ir analizuoti klaidas gamyboje. Populiarios paslaugos yra Sentry, Rollbar ir Bugsnag.
- Išbandykite klaidų tvarkymą: Parašykite vieneto testus, kad patikrintumėte, ar jūsų Error Boundaries teisingai tvarko skirtingus klaidų tipus.
- Apsvarstykite vartotojo patirtį: Rodykite informatyvius ir vartotojui patogius klaidų pranešimus, kurie padeda vartotojams išspręsti problemą. Venkite techninio žargono.
- Stebėkite klaidų dažnumą: Stebėkite skirtingų klaidų tipų dažnumą, kad nustatytumėte pasikartojančias problemas ir prioritetizuotumėte pataisymus.
- Tarptautinimas (i18n): Pateikdami klaidų pranešimus vartotojui, įsitikinkite, kad jūsų pranešimai yra tinkamai tarptautizuoti, kad būtų palaikomos skirtingos kalbos ir kultūros. Naudokite bibliotekas, pvz.,
i18nextarba React Context API, norėdami valdyti vertimus. - Prieinamumas (a11y): Įsitikinkite, kad jūsų klaidų pranešimai yra prieinami vartotojams su negalia. Naudokite ARIA atributus, kad suteiktumėte papildomą kontekstą ekrano skaitytuvams.
- Saugumas: Būkite atsargūs, kokią informaciją rodote klaidų pranešimuose, ypač gamybos aplinkoje. Venkite atskleisti slaptus duomenis, kurie gali būti išnaudoti užpuolikų. Pavyzdžiui, nerodykite žaliavinių klaidų pėdsakų galutiniams vartotojams.
Pavyzdys: API klaidų tvarkymas e. prekybos programoje
Apsvarstykite e. prekybos programą, kuri gauna informaciją apie produktą iš API. Galimi klaidų scenarijai yra šie:
- Tinklo klaidos: API serveris nepasiekiamas arba vartotojo interneto ryšys nutrūko.
- Autentifikacijos klaidos: Vartotojo autentifikavimo žetonas neteisingas arba pasibaigė.
- Resurso neradimo klaidos: Pageidaujamas produktas neegzistuoja.
- Serverio klaidos: API serveryje įvyksta vidinė klaida.
Naudojant Error Boundaries ir klaidų kategorizavimą, programa gali grakščiai tvarkyti šiuos scenarijus:
// Pavyzdys (supaprastintas)
async function fetchProduct(productId) {
try {
const response = await fetch(`/api/products/${productId}`);
if (!response.ok) {
if (response.status === 404) {
throw new Error("PRODUCT_NOT_FOUND");
} else if (response.status === 401 || response.status === 403) {
throw new Error("AUTHENTICATION_ERROR");
} else {
throw new Error("SERVER_ERROR");
}
}
return await response.json();
} catch (error) {
if (error instanceof TypeError && error.message === "Failed to fetch") {
throw new Error("NETWORK_ERROR");
}
throw error;
}
}
class ProductErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, errorDetails: null, errorInfo: null };
}
static getDerivedStateFromError(error) {
const errorDetails = handleCustomError(error.message); // Use errorMap as shown previously
return { hasError: true, errorDetails: errorDetails };
}
componentDidCatch(error, errorInfo) {
console.error("Caught error:", error, errorInfo);
this.setState({errorInfo: errorInfo});
}
render() {
if (this.state.hasError) {
const { message, retry } = this.state.errorDetails;
return (
<div>
<h2>Klaida!</h2>
<p>{message}</p>
{retry && <button onClick={() => window.location.reload()}>Bandykite dar kartą</button>}
</div>
);
}
return this.props.children;
}
}
Paaiškinimas:
fetchProductfunkcija tikrina API atsakymo būsenos kodą ir išmeta konkrečius klaidų tipus pagal būseną.ProductErrorBoundarykomponentas gaudo šias klaidas ir rodo atitinkamus klaidų pranešimus.- Esant tinklo ir serverio klaidoms, rodomas mygtukas „Bandykite dar kartą“, leidžiantis vartotojui dar kartą pabandyti pateikti užklausą.
- Esant autentifikavimo klaidoms, vartotojas gali būti nukreiptas į prisijungimo puslapį.
- Jei resursas nerastas, rodomas pranešimas, rodantis, kad produkto nėra.
Išvada
Klaidų kategorizavimas React Error Boundaries viduje yra būtinas kuriant atsparias, vartotojui patogias programas. Naudodami tokius metodus kaip instanceof patikrinimai, klaidų kodai ir centralizuotas klaidų atvaizdavimas, galite efektyviai tvarkyti skirtingus klaidų scenarijus ir suteikti geresnę vartotojo patirtį. Nepamirškite laikytis geriausios klaidų tvarkymo, registravimo ir testavimo praktikos, kad jūsų programa grakščiai tvarkytų netikėtas situacijas.
Įgyvendindami šias strategijas, galite žymiai pagerinti savo React programų stabilumą ir priežiūrą, suteikdami sklandesnę ir patikimesnę patirtį savo vartotojams, nepriklausomai nuo jų buvimo vietos ar kilmės.
Daugiau išteklių: